home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * PROGRAM: LEDUMP.C
- *
- * PURPOSE: Dump 'LE' file info
- *
- * Copyright 1997, Mike Wallace and Pete Davis
- *
- * Chapter 10, LE File Format, from Undocumented Windows File Formats,
- * published by R&D Books, an imprint of Miller Freeman, Inc.
- *
- **********************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <malloc.h>
- #include <windows.h>
- #include "ledump.h"
-
- /* Make this big thing global since we'll need it everywhere. */
- LEHEADER LEHeader;
- long LEStart; /* Keep track of start of LE Header */
-
-
- BOOL SkipMZ(FILE *LEFile)
- {
- MZHEADER MZHeader;
-
- fread(&MZHeader, sizeof(MZHeader), 1, LEFile);
- if (MZHeader.MZMagic[0] != 'M' || MZHeader.MZMagic[1] != 'Z')
- {
- printf("This is not an executable file!\n");
- return FALSE;
- }
-
- if (!MZHeader.LEOff)
- {
- printf("This is a DOS executable.\n");
- return FALSE;
- }
-
- fseek(LEFile, MZHeader.LEOff, SEEK_SET);
- return TRUE;
- }
-
- void DumpHeaderInfo()
- {
- DWORD Flags;
-
- Flags = LEHeader.ModuleFlags; /* Get it into an easier to type variable */
-
- printf("CPU Required: ");
- switch(LEHeader.CPUType)
- {
- case CPU_286:
- printf("80286\n");
- break;
- case CPU_386:
- printf("80386\n");
- break;
- case CPU_486:
- printf("80486\n");
- break;
- }
-
- printf("OS Required: ");
- switch(LEHeader.OSType)
- {
- case OS_UNKNOWN:
- printf("Unknown\n");
- break;
- case OS_OS2:
- printf("OS/2\n");
- break;
- case OS_WINDOWS:
- printf("Windows\n");
- break;
- case OS_DOS4X:
- printf("DOS 4.x\n");
- break;
- case OS_WINDOWS386:
- printf("Windows 386 Enhanced Mode\n");
- break;
- }
-
- printf("Initial EIP: %lX:%08lX\n", LEHeader.EIPObjNum, LEHeader.EIP);
- printf("Initial ESP: %lX:%08lX\n", LEHeader.ESPObjNum, LEHeader.ESP);
-
- printf("Flags: 0x%08lX\n", Flags);
- if (Flags & MOD_PERPROCESSLIBINIT)
- printf("- Per Process Library Initialization\n");
- if (Flags & MOD_INTERNALFIXUPS)
- printf("- Internal Fixups\n");
- if (Flags & MOD_EXTERNALFIXUPS)
- printf("- External Fixups\n");
- if ( (Flags & MOD_USES_PM) == MOD_USES_PM)
- printf("- Uses Presentation Manager\n");
- else
- {
- if (Flags & MOD_INCOMPAT_PM)
- printf("- Incompatible with Presentation Manager\n");
- if (Flags & MOD_COMPAT_PM)
- printf("- Compatible with Presentation Manager\n");
- }
- if (Flags & MOD_NOTLOADABLE)
- printf("- Module is not loadable.\n");
- if ( (Flags & MOD_PROTLIBMOD) == MOD_PROTLIBMOD)
- printf("- Protected Memory Library Module\n");
- else if ( (Flags & MOD_VIRTDEVICEDRVR) == MOD_VIRTDEVICEDRVR)
- printf("- Virtual Device Driver Module\n");
- else
- {
- if (Flags & MOD_LIBMOD)
- printf("- Library Module\n");
- if (Flags & MOD_PHYSDEVICEDRVR)
- printf("- Physical Device Driver\n");
- }
- if (Flags & MOD_PERPROCLIBTERM)
- printf("- Per-Process Library Termination\n");
-
- printf("\n");
- }
-
- void DumpObjectTable(FILE *LEFile)
- {
- DWORD i;
- OBJTBLENTRY ote;
-
- printf("There are %ld objects in the Object Table.\n", LEHeader.NumObjects);
-
- fseek(LEFile, LEStart + LEHeader.ObjTblOffset, SEEK_SET);
- for (i=1; i<=LEHeader.NumObjects; i++)
- {
- fread(&ote, sizeof(ote), 1, LEFile);
- printf("Segment #: %ld Size: 0x%08lX Reloc Addr: 0x%08lX # Pages: %ld\n",
- i, ote.VirtualSize, ote.RelocBaseAddr, ote.NumPgTblEntries);
- if (i == LEHeader.AutoDSObj)
- printf("Auto Data Segment\n");
- printf("Flags:\n");
- if (ote.ObjectFlags & OBJ_READABLE)
- printf("Readable\n");
- if (ote.ObjectFlags & OBJ_WRITEABLE)
- printf("Writeable\n");
- if (ote.ObjectFlags & OBJ_EXECUTABLE)
- printf("Executable\n");
- if (ote.ObjectFlags & OBJ_RESOURCE)
- printf("Resource\n");
- if (ote.ObjectFlags & OBJ_DISCARDABLE)
- printf("Discardable\n");
- if (ote.ObjectFlags & OBJ_SHARED)
- printf("Shared\n");
- if (ote.ObjectFlags & OBJ_PRELOAD)
- printf("Preload\n");
- if (ote.ObjectFlags & OBJ_INVALID)
- printf("Invalid\n");
- if ( (ote.ObjectFlags & OBJ_RESIDENTCONTIG) == OBJ_RESIDENTCONTIG)
- printf("Resident & Contiguous\n");
- else
- {
- if (ote.ObjectFlags & OBJ_ZEROFILLED)
- printf("Zero-Filled\n");
- if (ote.ObjectFlags & OBJ_RESIDENT)
- printf("Resident\n");
- }
- if (ote.ObjectFlags & OBJ_RESERVED)
- printf("Reserved\n");
- if (ote.ObjectFlags & OBJ_1616ALIAS)
- printf("16:16 Alias Required\n");
- if (ote.ObjectFlags & OBJ_BIGDEFAULT)
- printf("'Big' bit for segment descriptor\n");
- if (ote.ObjectFlags & OBJ_CONFORM)
- printf("Object is conforming to code\n");
- if (ote.ObjectFlags & OBJ_PRIVILEGE)
- printf("Object I/O privilege level\n");
- printf("\n");
- }
- }
-
- void DumpNameTable(FILE *LEFile, DWORD size)
- {
- DWORD Curr;
- BYTE len;
- char Name[257];
- WORD Ord;
-
- Curr = 0;
- while (Curr < size)
- {
- fread(&len, sizeof(len), 1, LEFile);
- Curr += (len + sizeof(len) + sizeof(Ord));
- fread(Name, len, 1, LEFile);
- Name[len] = 0x00;
- fread(&Ord, sizeof(Ord), 1, LEFile);
- printf("%u %s\n", Ord, Name);
- }
-
- }
-
- /* Dumps the Resident and Non-Resident Name Tables */
- void DumpNameTables(FILE *LEFile)
- {
- printf("\nResident Name Table\n");
- printf("Ordinal Name\n");
- fseek(LEFile, LEStart + LEHeader.ResNameTable, SEEK_SET);
- DumpNameTable(LEFile, (LEHeader.EntryTable - LEHeader.ResNameTable) - 1);
- printf("\n");
- printf("Non-Resident Name Table\n");
- printf("Ordinal Name\n");
- fseek(LEFile, LEHeader.NonResTable, SEEK_SET);
- DumpNameTable(LEFile, LEHeader.NonResSize - 1);
-
- }
- /*
- void DumpImports(FILE *LEFile)
- {
- FIXUPREC FixupRec;
- PROCBYNAME ProcByName;
- PROCBYORD ProcByOrd;
- long CurrLoc;
-
- fseek(LEFile, LEStart+LEHeader.FixupRecTable, SEEK_SET);
-
-
- }
- */
- void Check4HeaderSurprises()
- {
- if (LEHeader.ByteOrder != ORD_LITTLEENDIAN)
- printf("Byte Order is not Little Endian!\n");
- if (LEHeader.WordOrder != ORD_LITTLEENDIAN)
- printf("Word Order is not Little Endian!\n");
-
- if (LEHeader.CPUType < CPU_386)
- printf("Doesn't require a 386 or better!\n");
- if (LEHeader.OSType != OS_WINDOWS386)
- printf("Not a Windows386 VxD!\n");
-
- if (LEHeader.ResourceTbl)
- printf("Resource Table Found!\n");
- if (LEHeader.NumResources)
- printf("Num Resources Found!\n");
- if (LEHeader.ModDirectTable)
- printf("Module Directive Table Found!\n");
- if (LEHeader.NumModDirect)
- printf("NumModDirect Found!\n");
- if (LEHeader.NumInstPreload)
- printf("Instance Preloads Found!\n");
- if (LEHeader.NumInstDemand)
- printf("Instance Demands Found!\n");
- if (LEHeader.FixupChecksum)
- printf("Fixup Checksum Found!\n");
- if (LEHeader.LoaderChecksum)
- printf("Loader Checksum Found!\n");
- if (LEHeader.PerPageChecksum)
- printf("Per-Page Checksum Found!\n");
- if (LEHeader.NonResChecksum)
- printf("Non-Resident Name Table Checksum Found!\n");
- }
-
- void DumpLEFile(FILE *LEFile)
- {
- LEStart = ftell(LEFile);
-
- fread(&LEHeader, sizeof(LEHeader), 1, LEFile);
- if (LEHeader.LEMagic[0] != 'L' || LEHeader.LEMagic[1] != 'E')
- {
- printf("This is not an 'LE' executable.\n\n");
- return;
- }
-
- DumpHeaderInfo();
-
- Check4HeaderSurprises();
-
- DumpObjectTable(LEFile);
-
- DumpNameTables(LEFile);
-
- // if (LEHeader.NumImports)
- // DumpImports(LEFile);
-
- }
-
- void Usage(void)
- {
- printf("Usage: LEDump filename[.386]\n\n");
- }
-
- int main(int argc, char *argv[])
- {
-
- char filename[256];
- FILE *LEFile;
-
- if (argc < 2) {
- Usage();
- return EXIT_FAILURE;
- }
-
- strcpy(filename, argv[1]);
-
- if (!strchr(filename, '.'))
- strcat(filename, ".386");
-
- if ((LEFile = fopen(filename, "rb")) == NULL) {
- printf("%s does not exist!\n", filename);
- return EXIT_FAILURE;
- }
-
- if (SkipMZ(LEFile))
- {
- printf("Dumping %s\n", filename);
- DumpLEFile(LEFile);
- }
- fclose(LEFile);
- return EXIT_SUCCESS;
- }
-
-